#pragma once

#include <QString>
#include <QColor>

#include "Export.hpp"

namespace Qt
{
	class Style
	{
	public:

		virtual
			~Style() = default;

	private:

		virtual void
			loadJsonText(QString jsonText) = 0;

		virtual void
			loadJsonFile(QString fileName) = 0;

		virtual void
			loadJsonFromByteArray(QByteArray const &byteArray) = 0;
	};

	class NODE_EDITOR_PUBLIC NodeStyle : public Style
	{
	public:

		NodeStyle();

		NodeStyle(QString jsonText);

	public:

		static void setNodeStyle(QString jsonText);

	private:

		void loadJsonText(QString jsonText) override;

		void loadJsonFile(QString fileName) override;

		void loadJsonFromByteArray(QByteArray const &byteArray) override;

	public:

		QColor NormalBoundaryColor;
		QColor SelectedBoundaryColor;
		QColor GradientColor0;
		QColor GradientColor1;
		QColor GradientColor2;
		QColor GradientColor3;
		QColor ShadowColor;
		QColor FontColor;
		QColor FontColorFaded;

		QColor HotKeyColor0;
		QColor HotKeyColor1;
		QColor HotKeyColor2;

		QColor ConnectionPointColor;
		QColor FilledConnectionPointColor;

		QColor WarningColor;
		QColor ErrorColor;

		float PenWidth;
		float HoveredPenWidth;

		float ConnectionPointDiameter;

		float Opacity;
	};

	class NODE_EDITOR_PUBLIC ConnectionStyle : public Style
	{
	public:

		ConnectionStyle();

		ConnectionStyle(QString jsonText);

	public:

		static void setConnectionStyle(QString jsonText);

	private:

		void loadJsonText(QString jsonText) override;

		void loadJsonFile(QString fileName) override;

		void loadJsonFromByteArray(QByteArray const &byteArray) override;

	public:

		QColor constructionColor() const;
		QColor normalColor() const;
		QColor normalColor(QString typeId) const;
		QColor selectedColor() const;
		QColor selectedHaloColor() const;
		QColor hoveredColor() const;

		float lineWidth() const;
		float constructionLineWidth() const;
		float pointDiameter() const;

		bool useDataDefinedColors() const;

	private:

		QColor ConstructionColor;
		QColor NormalColor;
		QColor SelectedColor;
		QColor SelectedHaloColor;
		QColor HoveredColor;

		float LineWidth;
		float ConstructionLineWidth;
		float PointDiameter;

		bool UseDataDefinedColors;
	};

	class NODE_EDITOR_PUBLIC FlowViewStyle : public Style
	{
	public:

		FlowViewStyle();

		FlowViewStyle(QString jsonText);

	public:

		static void setStyle(QString jsonText);

	private:

		void loadJsonText(QString jsonText) override;

		void loadJsonFile(QString fileName) override;

		void loadJsonFromByteArray(QByteArray const &byteArray) override;

	public:

		QColor BackgroundColor;
		QColor FineGridColor;
		QColor CoarseGridColor;
	};

	class NODE_EDITOR_PUBLIC StyleCollection
	{
	public:

		static
			NodeStyle const&
			nodeStyle();

		static
			ConnectionStyle const&
			connectionStyle();

		static
			FlowViewStyle const&
			flowViewStyle();

	public:

		static
			void
			setNodeStyle(NodeStyle);

		static
			void
			setConnectionStyle(ConnectionStyle);

		static
			void
			setFlowViewStyle(FlowViewStyle);

	private:

		StyleCollection() = default;

		StyleCollection(StyleCollection const&) = delete;

		StyleCollection&
			operator=(StyleCollection const&) = delete;

		static
			StyleCollection&
			instance();

	private:

		NodeStyle _nodeStyle;

		ConnectionStyle _connectionStyle;

		FlowViewStyle _flowViewStyle;
	};
}
